﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Common;
using System.Net.Mail;
using DSAAssignment.Models;
using System.Drawing;

namespace DSAAssignment.Controllers
{
    public class ProductController : Controller
    {
        //
        // GET: /Product/

        public ActionResult Details(int id)
        {
            Product p = new ProductServ.ProductServicesClient().GetProductByID(id);
            DSAAssignment.Models.ProductDetailModel pd = new ProductDetailModel();
            pd.ID = p.ID;
            pd.Name = p.Name;
            pd.Price = (double)p.Price;
            pd.StockAvailable = (int)p.StockAmount;
            pd.Features = p.Features;
            pd.Image = p.Image;
            pd.NumberOfRatings = new ProductServ.ProductServicesClient().getAllRatings().Where(x => x.ProductID == p.ID).Count();
            if (pd.NumberOfRatings == 0)
                pd.AverageRating = 0;
            else
                pd.AverageRating = new ProductServ.ProductServicesClient().getAllRatings().Where(x => x.ProductID == p.ID).Sum(x => x.Rating) / pd.NumberOfRatings;

            return View("Details", pd);
        }

        public ActionResult PurchaseItemDetail(int id)
        {
            Common.VIews.UserItem p = new ProductServ.ProductServicesClient().GetUserProductsDetails(HttpContext.User.Identity.Name, id);
            return View("PurchaseItemDetail", p);
        }

        private int ProductID { get; set; }
        public ActionResult ProductRatings(int productID)
        {
            ProductID = productID;
            DSAAssignment.Models.RateProductModel rm = new RateProductModel();
            rm.ProductID = productID;
            List<int> ratings = new List<int>();
            for (int i = 0; i <= 5; i++)
            {
                ratings.Add(i);
            }
            rm.RatingList = new SelectList(ratings);
            return View("ProductRatings", rm);
        }


        [HttpPost]
        public ActionResult ProductRatings(DSAAssignment.Models.RateProductModel r)
        {
            Common.UserProductRating rate = new UserProductRating();
            rate.ProductID = r.ProductID;
            rate.UserName = HttpContext.User.Identity.Name;
            rate.Rating = r.Rating;
            new ProductServ.ProductServicesClient().AddRating(rate);
            Common.Product p = new ProductServ.ProductServicesClient().GetProductByID(ProductID);
            return RedirectToAction("Details", p);
        }

        [HttpPost]
        public void AddProductsToCart(int productID, int quantity)
        {
            new ProductServ.ProductServicesClient().AddToCart(HttpContext.User.Identity.Name, productID, quantity);
        }

        public ActionResult ShoppingCart()
        {
            List<DSAAssignment.Models.CartModel> Cart = new List<Models.CartModel>();
            DSAAssignment.Models.CartModel ShoppingCart;

            foreach (Common.Cart c in new ProductServ.ProductServicesClient().GetItemsInShoppingCart(HttpContext.User.Identity.Name))
            {
                ShoppingCart = new Models.CartModel();
                Product p = new ProductServ.ProductServicesClient().GetProductByID((int)c.ProductID);
                ShoppingCart.CartID = c.ID;
                ShoppingCart.ProductID = p.ID;
                ShoppingCart.ProductName = p.Name;
                ShoppingCart.Quantity = (int)c.Quantity;
                ShoppingCart.Image = p.Image;
                Cart.Add(ShoppingCart);
            }
            return View("ShoppingCart", Cart);
        }

        public int NoOfItemInShopppingCart()
        {
            return new ProductServ.ProductServicesClient().GetNoOfItemsInShoppingCart(HttpContext.User.Identity.Name);
        }

        public ActionResult PlaceOrder()
        {

            Common.Order O = new Order();
            O.ID = Guid.NewGuid();
            O.Date = DateTime.Now;
            O.UserName = HttpContext.User.Identity.Name;


            new ProductServ.ProductServicesClient().AddOrder(O);

            foreach (Cart c in new ProductServ.ProductServicesClient().GetItemsInShoppingCart(HttpContext.User.Identity.Name))
            {
                OrderDetail p = new OrderDetail();
                p.ProductID = (int)c.ProductID;
                p.Quantity = (int)c.Quantity;
                p.OrderID = O.ID;
                new ProductServ.ProductServicesClient().AddOrderDetails(p);

                new ProductServ.ProductServicesClient().DeleteCart(c.ID);
            }

            try
            {
                MailMessage mail = new MailMessage();
                SmtpClient SmtpServer = new SmtpClient("smtp.gmail.com");

                mail.From = new MailAddress("andreaconsiglio2@gmail.com");
                mail.To.Add(new UserServ.UserServicesClient().GetUserByUserName(O.UserName).Email);
                mail.Subject = "Order Invoice";
                mail.Body = "Dear " + O.UserName + "\n This Email is being sent to infrom you that an order has been placed to " + O.User.HouseNo + ", "
                    + O.User.StreetName + ", " + O.User.TownName + "\n Order ID is :" + O.ID;

                SmtpServer.Port = 587;
                SmtpServer.Credentials = new System.Net.NetworkCredential("andreaconsiglio2@gmail.com", "Andrea79904782");
                SmtpServer.EnableSsl = true;

                SmtpServer.Send(mail);
            }
            catch (Exception)
            {
                ModelState.AddModelError("", "NO internet Connection Dummy");
            }

            List<Product> Products = new ProductServ.ProductServicesClient().GetAllProducts();
            return RedirectToAction("HomePage", "Home", Products);
        }

        public ActionResult RemoveProductFromCart(int cartID)
        {
            new ProductServ.ProductServicesClient().RemoveProductFromCart(cartID);

            if (NoOfItemInShopppingCart() == 0)
                return RedirectToAction("HomePage", new ProductServ.ProductServicesClient().GetAllProducts());
            else
                return ShoppingCart();
        }


        [HttpPost]
        public ActionResult Comment(Comment com)
        {
            com.Date = DateTime.Now;
            com.UserName = HttpContext.User.Identity.Name;
            new ProductServ.ProductServicesClient().addComment(com);
            return RedirectToAction("Details", new ProductServ.ProductServicesClient().GetProductByID(com.ProductID));
        }

        public ActionResult MostBoughtItems()
        {
            List<Common.Views.ProductReport> products = new List<Common.Views.ProductReport>();
            foreach (Common.OrderDetail OD in new ProductServ.ProductServicesClient().GettAllOrdersDetails())
            {
                if (products.Count == 0)
                {
                    Common.Views.ProductReport pr = new Common.Views.ProductReport();
                    pr.ProductID = OD.ProductID;
                    pr.ProductName = OD.Product.Name;
                    pr.NoOfTimesBought = OD.Quantity;
                    products.Add(pr);
                }

                else
                {
                    foreach (Common.Views.ProductReport pr in products)
                    {
                        if (OD.ProductID == pr.ProductID)
                        {
                            pr.NoOfTimesBought += OD.Quantity;
                            break;
                        }
                        else
                        {
                            Common.Views.ProductReport p2 = new Common.Views.ProductReport();
                            p2.ProductID = OD.ProductID;
                            p2.ProductName = OD.Product.Name;
                            p2.NoOfTimesBought = OD.Quantity;
                            products.Add(p2);
                            break;
                        }

                    }

                }
            }
            products.OrderByDescending(x => x.NoOfTimesBought).ToList();
            new ProductServ.ProductServicesClient().ProduceReport(products, "Most Purchased");
            return RedirectToAction("ReportsView", "Home");
        }

        public ActionResult MostRatedProduct()
        {
            List<Common.Views.ProductReport> products = new List<Common.Views.ProductReport>();
            Common.Views.ProductReport pr = new Common.Views.ProductReport();
            foreach (Common.UserProductRating uf in new ProductServ.ProductServicesClient().getAllRatings())
            {
                if (products.Count == 0)
                {
                    pr.ProductID = uf.ProductID;
                    pr.ProductName = uf.Product.Name;
                    pr.ProductRating = uf.Rating;
                    products.Add(pr);
                }

                else
                {
                    foreach (Common.Views.ProductReport PR in products)
                    {
                        if (uf.ProductID == PR.ProductID)
                        {
                            PR.ProductRating += uf.Rating;
                            break;
                        }
                        else
                        {
                            Common.Views.ProductReport p2 = new Common.Views.ProductReport();
                            p2.ProductID = uf.ProductID;
                            p2.ProductName = uf.Product.Name;
                            p2.ProductRating = uf.Rating;
                            products.Add(p2);
                            break;
                        }

                    }
                }
            }
            foreach (Common.Views.ProductReport p in products)
            {
                p.ProductRating = p.ProductRating / products.Count;
            }

            products.OrderByDescending(x => x.ProductRating).ToList();
            new ProductServ.ProductServicesClient().ProduceReport(products, "Highly Rated");
            return RedirectToAction("ReportsView", "Home");
        }

        public ActionResult ProductsWithHighestFaults()
        {
            new ProductServ.ProductServicesClient().ProduceReport(Faults().OrderByDescending(x => x.NoOfFaultsReported).ToList(), "Highest faults");
            return RedirectToAction("ReportsView", "Home");
        }

        public ActionResult ProductsWithLowestFaults()
        {
            new ProductServ.ProductServicesClient().ProduceReport(Faults().OrderBy(x => x.NoOfFaultsReported).ToList(), "Lowest faults");
            return RedirectToAction("ReportsView", "Home");
        }

        public List<Common.Views.ProductReport> Faults()
        {
            List<Common.Views.ProductReport> fault = new List<Common.Views.ProductReport>();
            foreach (Common.UserProductFault f in new FaultServ.FaultServiceClient().getAllFaults())
            {
                if (fault.Count == 0)
                {
                    Common.Views.ProductReport pr = new Common.Views.ProductReport();
                    pr.ProductID = (int)f.ProductID;
                    pr.ProductName = f.Product.Name;
                    pr.NoOfFaultsReported = 1;
                    fault.Add(pr);
                }
                else
                {
                    foreach (Common.Views.ProductReport pr in fault)
                    {
                        if (f.ProductID == pr.ProductID)
                        {
                            pr.NoOfFaultsReported += 1;
                            break;
                        }
                        else
                        {
                            Common.Views.ProductReport pr2 = new Common.Views.ProductReport();
                            pr2.ProductID = (int)f.ProductID;
                            pr2.ProductName = f.Product.Name;
                            pr2.NoOfFaultsReported = 1;
                            fault.Add(pr2);
                            break;
                        }
                    }
                }
            }

            return fault;
        }


        public ActionResult GetUserProduct()
        {
            List<Common.VIews.UserItem> list = new ProductServ.ProductServicesClient().GetUserProducts(HttpContext.User.Identity.Name);
            return View("UserProducts", list);
        }

        public ActionResult ManageFaults()
        {
            List<Common.VIews.UserItem> list = new ProductServ.ProductServicesClient().GetUserProductsForFaults(HttpContext.User.Identity.Name);
            return View("ManageFaults", list);
        }

        public ActionResult ReportProductFaults(FaultLogin fl)
        {
            string TicketNumber = new FaultServ.FaultServiceClient().GenerateNumber();
            if (new FaultServ.FaultServiceClient().FaultLogin(fl.UserName, fl.Token, fl.Pin) == true)
            {
                byte[] imgbyte = new BarCodeServ.BarCodeSoapClient().Code39(TicketNumber, 10, true, "Userbarcode");
                System.IO.MemoryStream ms = new System.IO.MemoryStream(imgbyte);
                Image img = Image.FromStream(ms);

                try
                {
                    MailMessage mail = new MailMessage();
                    SmtpClient SmtpServer = new SmtpClient("smtp.gmail.com");

                    mail.From = new MailAddress("andreaconsiglio2@gmail.com");
                    mail.To.Add(new UserServ.UserServicesClient().GetUserByUserName(fl.UserName).Email);
                    mail.Subject = "Fault Reported";
                    mail.Body = "This Email is being sent as a recipt of your recent Fault Report .Please Make sure to save this Ticket Number " + TicketNumber + " As you will needed as a confirmation \n here is your barcode : " + img;

                    SmtpServer.Port = 587;
                    SmtpServer.Credentials = new System.Net.NetworkCredential("andreaconsiglio2@gmail.com", "Andrea79904782");
                    SmtpServer.EnableSsl = true;

                    SmtpServer.Send(mail);
                }
                catch (Exception)
                {
                    ModelState.AddModelError("", "Something Wrong your information didnt meet my expectations :P");
                }
            }

            return View("ManageFaults","Home");
        }

        public ActionResult ItemFaultDetail(int id, DateTime startdate, DateTime EndDate)
        {
            List<Common.UserProductFault> list = new FaultServ.FaultServiceClient().ListOfItemFaults(id, startdate, EndDate, HttpContext.User.Identity.Name);
            return View("ItemFaultDetail", list);
        }

        public ActionResult MyOrders(string ID)
        {
            System.Diagnostics.Process.Start(@"C:\\Users\\Andrea Consiglio\\Desktop\\" + ID + ".pdf");
            return RedirectToAction("MyOrders", "Home");
        }

        public ActionResult UpdateFault(int id)
        {
            DSAAssignment.Models.FaultModel model = new Models.FaultModel();
            foreach (UserProductFault f in new FaultServ.FaultServiceClient().getAllFaults())
            {
                if (id == f.FaultID)
                {
                    Fault status = new FaultServ.FaultServiceClient().getFaultStatusByID((int)f.FaultID);
                    model.UserFaultID = f.ID;
                    model.FaultStatus = status.Fault1;
                    model.ProductID = (int)f.ProductID;
                    model.ProductName = f.Product.Name;
                    model.FaultDescription = f.FaultDetail;
                    model.FaultID = (int)f.FaultID;
                    model.UserName = f.UserName;
                    model.FaultReports = new FaultServ.FaultServiceClient().GetAllFaultStatus();
                    model.FaultReportsList = new SelectList(new FaultServ.FaultServiceClient().GetAllFaultStatus(), "ID", "Fault1");
                }
            }
            return View("UpdateFault", model);
        }

        [HttpPost]
        public ActionResult UpdateFault(DSAAssignment.Models.FaultModel model)
        {
            UserProductFault fault = new FaultServ.FaultServiceClient().getFaultByID(model.UserFaultID);
            fault.FaultID = model.FaultID;
            new FaultServ.FaultServiceClient().UpdateFault(fault);

            FaultLog log = new FaultLog();
            log.FaultID = fault.ID;
            new FaultServ.FaultServiceClient().addFaultLog(log);

            //This WebService Sends a message with a cost
            //new SMSServ.SendSMSWorldSoapClient().sendSMS("Andreaconsiglio2@gmail.com","356",fault.User.MobileNo.ToString(),"Hello this Sms is being sent to notify you that your Product Fault Has Be Updated");
            
            return Redirect("~/Home/ManageFaults");
        }

        public ActionResult ReportFault(int prodId, Guid OrderID)
        {
            bool res = false;
            UserProductFault fault = new UserProductFault();
            Order p = new ProductServ.ProductServicesClient().GetOrderByID(OrderID);

            if (p.Date.AddYears(2) > DateTime.Now)
            {
                foreach (UserProductFault fa in new FaultServ.FaultServiceClient().getAllFaults())
                {
                    if (prodId != fa.ProductID &&  OrderID != fa.OrderID)
                    {

                        fault.ProductID = prodId;
                        fault.OrderID = OrderID;
                        res = true;

                    }
                    else
                    {
                        res = false;
                        break;
                    }
                }

            }


            if (res == true)
            {
                return View("ReportFault", fault);
            }
            else
            {
                return Redirect("~/Home/MyPurchasedItems");
            }

        }

        public ActionResult ProductsList(string username)
        {
            return Json(new[] { new ProductServ.ProductServicesClient().GetAllUserProducts(username) }, JsonRequestBehavior.AllowGet);
        }

    }
}
